home *** CD-ROM | disk | FTP | other *** search
- ******************************************************************************
- * FREXX PROGRAMMING LANGUAGE *
- ******************************************************************************
-
- * liballoc.a
-
- * Stack allocation/checking/expanding routines.
-
- * Authors: Kjell Ericson and Daniel Stenberg
-
- ******************************************************************************
-
- ************************************************************************
- * *
- * fpl.library - A shared library interpreting script langauge. *
- * Copyright (C) 1992-1994 FrexxWare *
- * Author: Daniel Stenberg *
- * *
- * This program is free software; you may redistribute for non *
- * commercial purposes only. Commercial programs must have a written *
- * permission from the author to use FPL. FPL is *NOT* public domain! *
- * Any provided source code is only for reference and for assurance *
- * that users should be able to compile FPL on any operating system *
- * he/she wants to use it in! *
- * *
- * You may not change, resource, patch files or in any way reverse *
- * engineer anything in the FPL package. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
- * *
- * Daniel Stenberg *
- * Ankdammsgatan 36, 4tr *
- * S-171 43 Solna *
- * Sweden *
- * *
- * FidoNet 2:201/328 email:dast@sth.frontec.se *
- * *
- ************************************************************************
-
- ; LibAlloc.a
- ;
- ; Allocate and expands the stack at need. a6 is always the FPLBase
- ; pointer when any of these routine are called!
-
- CSECT LibAlloc
-
- xdef _GetStackUsed ; long GetStackUsed(struct Data *);
- xdef _InitStack ; void InitStack(struct Data *)
- xdef _CheckStack ; long OK= CheckStack(struct Data *,
- ; long maxstack,
- ; long minstack);
- xdef _InterfaceCall ; long InterfaceCall(struct Data *,
- ; void **);
- ; func pointer);
- xdef _InterfaceCallNoStack ; long InterfaceCallNoStack(
- ; struct Data *,
- ; void **);
- ; func pointer);
- xdef _StoreRegisters ; void StoreRegisters(stuct Data *);
- xref _Script ; call this function!
-
- xref _Malloc ; malloc routine
- xref _Free ; free routine
-
- IFD LOCKFUNTIONS_WANTED
-
- xdef _Locker ; void Locker(long *data, char bit);
- xdef _Unlocker ; void Unlocker(long *data, char bit);
-
- ENDC
-
- include "exec/memory.i"
- include "exec/tasks.i"
- include "liballoc.i"
-
- asALLOCSTACK equ 5000 ; Number of bytes added to current size when reallocing
- asINITCOPY equ 100 ; Amout of memory copied from stack (even 4)
- MALLOC_STATIC equ 1 ; Static allocation type specifier
-
- _InitStack: ; struct Data * in A2
- ; struct Expr * in A3
- ; short control in D2
- ; struct Condition * in A1
-
- move.l sp,DATA_EXT_STACK(a2) ; store external stack pointer
- move.l DATA_INT_STACK(a2),sp ; internal stack pointer in A0
-
- move.l DATA_TASK(a2),a0 ; get task pointer in A0
-
- move.l TC_SPUPPER(a0),DATA_OLDTOP(a2) ; upper
- move.l TC_SPLOWER(a0),DATA_OLDBOT(a2) ; lower
-
- move.l DATA_STACKBASE(a2),d0 ; get stack base in D0
- add.l DATA_STACKSIZE(a2),d0 ; add stack size
- move.l d0,TC_SPUPPER(a0) ; set new stack upper bound
-
- move.l DATA_STACKBASE(a2),TC_SPLOWER(a0) ; set new stack lower bound
-
- bsr _Script ; don't mess with D0!!
-
- move.l DATA_TASK(a2),a0 ; get task pointer in A0
- move.l TC_SPLOWER(a0),DATA_STACKBASE(a2) ; get new stack lower bound
-
- move.l DATA_OLDBOT(a2),TC_SPLOWER(a0) ; set lower bounds
- move.l DATA_OLDTOP(a2),TC_SPUPPER(a0) ; set upper bounds
-
- move.l sp,DATA_INT_STACK(a2) ; store internal stack pointer
- move.l DATA_EXT_STACK(a2),sp ; external stack pointer
-
- rts
-
- _GetStackUsed: ;(struct Data * - A0)
- move.l a1,-(sp) ; backup A1
- move.l DATA_STACKBASE(a0),a1 ; stack base address
- move.l sp,d0 ; get stack pointer to d0
- sub.l a1,d0 ; subtract stack base pointer
- move.l (sp)+,a1 ; restore A1
- rts
-
- _CheckStack: ;(struct Data * - A3; stack limit - D2 ; stack margin - D3)
- movem.l d1/a0/a1/a2,-(sp) ; [PUSH]
-
- move.l DATA_STACKBASE(a3),a0 ; stack base address in A0
-
- move.l sp,d0 ; stack pointer in D0
- sub.l a0,d0 ; subtract stack base
- cmp.l d3,d0 ; stack usage larger than margin?
- bpl csend ; no? return!
- move.l DATA_STACKSIZE(a3),d0 ; current stack size to D0
-
- add.l d3,d0 ; add margin size to stack size
-
- cmp.l d0,d2 ; Compare with the stack limit
-
- bmi csend3 ; reached stack limit, fail!
-
- movem.l d0/a0,-(sp) ; size in D0 [PUSH]
- move.b #MALLOC_STATIC,d1 ; type
- move.l a3,a0 ; struct Data *
- IFD DEBUG
- lea.l sourcename,a1
- clr.l d2
- ENDC
- jsr _Malloc ; get memory
- movem.l (sp)+,d1/a0 : [POP] size is now in D1
-
- tst.l d0 ; Did we get memory?
- beq.s csend2 ; no memory, fail!
- move.l d0,a2 ; memory pointer (stack base) in A2
- move.l d1,DATA_STACKSIZE(a3) ; store size in Data struct!
-
- move.l d1,d0 ; get new size in D0
- sub.l d3,d0 ; subtract the addition to get old
-
- movem.l a2/a3,-(sp) ; [PUSH]
- move.l a0,a1 ; old stack base to A1
- sub.l d0,a2 ; subtract old size from new base
- add.l d1,a2 ; add new size to new base
- ; old size is in D0
- sub.l #4,d0 ; count down four bytes now
-
- cslo1: move.l (a1)+,(a2)+ ; move
- sub.l #4,d0
- bpl.s cslo1 ; while positive, loop!
-
- movem.l (sp)+,a2/a3 ; [POP]
- move.l sp,a1 ; stack pointer to A1
- sub.l a0,a1 ; subtract old stack base
- add.l a2,a1 ; add new stack base
- add.l d3,a1 ; add margin size
- ; add.l #asALLOCSTACK,a1 ; add stack realloc size
- move.l a1,sp ; SET NEW STACK POINTER!!!
-
- move.l DATA_TASK(a3),a1 ; get task pointer in A1
-
- move.l a2,d0 ; get stack base in D0
- add.l DATA_STACKSIZE(a3),d0 ; add stack size
- move.l d0,TC_SPUPPER(a1) ; set new stack upper bound
-
- move.l a2,TC_SPLOWER(a1) ; set new stack lower bound
-
- ; Deallocate old stack
- movem.l a2/a3,-(sp) ; [PUSH]
-
- move.l a0,a1 ; memory pointer to A1
- move.l a3,a0 ; struct Data * to A0
- move.b #MALLOC_STATIC,d0 ; type to D0
- jsr _Free
- movem.l (sp)+,a2/a3 ; [POP]
-
- move.l a2,DATA_STACKBASE(a3) ; Store the new value
- csend: ; OK
- moveq.l #0,d0
- movem.l (sp)+,d1/a0/a1/a2 ; [POP]
- rts
- csend2: ; OUT OF MEM
- moveq.l #1,d0
- movem.l (sp)+,d1/a0/a1/a2 ; [POP]
- rts
- csend3: ; MAX STACK REACHED
- moveq.l #2,d0
- movem.l (sp)+,d1/a0/a1/a2 ; [POP]
- rts
-
-
- _InterfaceCall: ; struct Data * in A1
- ; void * in A0
- ; function pointer in A2
-
- movem.l d2-d7/a1/a3-a6,-(sp) ; store registers
- move.l DATA_TASK(a1),a3
-
- move.l DATA_OLDTOP(a1),TC_SPUPPER(a3) ; upper
- move.l DATA_OLDBOT(a1),TC_SPLOWER(a3) ; lower
- move.l sp,DATA_INT_STACK(a1) ; set internal pointer
- move.l DATA_EXT_STACK(a1),sp ; set external pointer
-
- lea DATA_REGISTERSTORAGE(a1),a3 ; get register buffer
- move.l a1,-(sp) ; store struct Data *
- movem.l (a3),d2-d7/a3-a6 ; get registers from buffer
- jsr (a2) ; call interface function
- ; DON'T MESS WITH D0!!!
-
- move.l (sp)+,a1 ; get struct Data * in A1
-
- move.l sp,DATA_EXT_STACK(a1)
- move.l DATA_INT_STACK(a1),sp
-
- move.l DATA_TASK(a1),a2
- move.l TC_SPUPPER(a2),DATA_OLDTOP(a1) ; upper
- move.l TC_SPLOWER(a2),DATA_OLDBOT(a1) ; lower
-
- move.l DATA_STACKBASE(a1),d1 ; get stack base in D1
- move.l d1,TC_SPLOWER(a2) ; set new stack lower bound
- add.l DATA_STACKSIZE(a1),d1 ; add stack size
- move.l d1,TC_SPUPPER(a2) ; set new stack upper bound
-
- movem.l (sp)+,d2-d7/a1/a3-a6 ; restore old registers
- rts
-
- _InterfaceCallNoStack: ; struct Data * in A1
- ; void * in A0
- ; function pointer in A2
-
- movem.l d2-d7/a1/a3-a6,-(sp) ; store registers
- lea DATA_REGISTERSTORAGE(a1),a3 ; get register buffer
- movem.l (a3),d2-d7/a3-a6 ; get registers from buffer
- jsr (a2) ; call interface function
- ; DON'T MESS WITH D0!!!
- movem.l (sp)+,d2-d7/a1/a3-a6 ; restore old registers
- rts
-
- _StoreRegisters: ; struct Data * in A0
- lea DATA_REGISTERSTORAGE(a0),a0 ; get register buffer address
- movem.l d2-d7/a3-a6,(a0) ; store registers in buffer
- rts
-
- IFD DEBUG
- sourcename:
- dc.b 'liballoc.a'
- ENDC
-
-
- IFD LOCKFUNCTIONS_WANTED
-
- _Locker: ; long *data in A0
- ; char bit in D0
-
- bset d0,(a0)
- bne.s _Locker
- rts
-
- _Unlocker: ; long *data in A0
- ; char bit in D0
-
- bclr d0,(a0)
- rts
-
- ENDC
-
- END
-